﻿@using Microsoft.AspNetCore.Html;
@using SimpleIdServer.IdServer.Website.Resources;
@using SimpleIdServer.IdServer.Website.Stores.ApiResourceStore;
@using SimpleIdServer.IdServer.Website.Stores.ScopeStore;
@using SimpleIdServer.IdServer.Website.Stores.UserStore;
@inherits Fluxor.Blazor.Web.Components.FluxorComponent
@inject ContextMenuService contextMenuService
@inject DialogService dialogService
@inject IDispatcher dispatcher
@inject IState<ApiResourcesState> searchApiResourcesState
@inject NotificationService notificationService

<div class="mb-1">
    <RadzenButton Click="@(args => AddResource())" Icon="add" Text="@Global.AddApiResource" ButtonStyle="ButtonStyle.Primary" Size="ButtonSize.Medium"></RadzenButton>
</div>

<p class="text-muted">
    @((MarkupString)(Global.ScopeResourcesDescription))
</p>

<div class="mt-3">
    <RadzenRow Gap="1rem">
        <RadzenColumn Size="5">
            <h4>@Global.AvailableResources</h4>
            <RadzenDataGrid @ref="grid"
                            AllowFiltering="true"
                            AllowColumnResize="true"
                            AllowAlternatingRows="false"
                            AllowSorting="true"
                            PageSize="30"
                            AllowPaging="true"
                            PagerHorizontalAlign="HorizontalAlign.Left"
                            ShowPagingSummary="true"
                            IsLoading="false"
                            LoadData="@LoadData"
                            RowRender="@RowRender"
                            Count="@searchApiResourcesState.Value.AvailableCount"
                            Data="@searchApiResourcesState.Value.AvailableApiResources"
                            TItem="SelectableApiResource"
                            ColumnWidth="300px">
                <Columns>
                    <RadzenDataGridColumn TItem="SelectableApiResource" Filterable="false" Sortable="false" Width="80px" TextAlign="TextAlign.Center">
                        <HeaderTemplate>
                            <RadzenCheckBox @bind-Value=@selectAllAvailable Change="@(args => ToggleAvailableAll(args))" TValue="bool" />
                        </HeaderTemplate>
                        <Template Context="data">
                            <RadzenCheckBox @bind-Value=@data.IsSelected Change="@(args => ToggleAvailableChanged(args, data))" TValue="bool" />
                        </Template>
                    </RadzenDataGridColumn>
                    <RadzenDataGridColumn TItem="SelectableApiResource" Property="Value.Name" Title="@Global.Resource" Filterable="false" Sortable="false" Width="80px" />
                    <RadzenDataGridColumn TItem="SelectableApiResource" Property="Value.Audience" Title="@Global.Audience" Filterable="false" Sortable="false" Width="80px" />
                    <RadzenDataGridColumn TItem="SelectableApiResource" Property="Value.Description" Title="@Global.Description" Filterable="false" Sortable="false" Width="80px" />
                    <RadzenDataGridColumn TItem="SelectableApiResource" Filterable="false" Sortable="false" Width="80px" TextAlign="TextAlign.Center">
                        <Template Context="data">
                            <RadzenButton Icon="more_vert" Click="@(args => ShowMoreContextMenu(data, args))" />
                        </Template>
                    </RadzenDataGridColumn>
                </Columns>
            </RadzenDataGrid>
        </RadzenColumn>
        <RadzenColumn>
            <RadzenStack>
                <RadzenButton Text="@Global.AssignResources" Icon="add" Click="@(() => Assign())" ButtonStyle="ButtonStyle.Primary" />
                <RadzenButton Text="@Global.UnassignResources" Icon="remove" Click=@(() => Unassign()) ButtonStyle="ButtonStyle.Primary" />
            </RadzenStack>
        </RadzenColumn>
        <RadzenColumn Size="5">
            <h4>@Global.AssignedResources</h4>
            <RadzenDataGrid @ref="grid"
                            AllowFiltering="true"
                            AllowColumnResize="true"
                            AllowAlternatingRows="false"
                            AllowSorting="true"
                            PageSize="30"
                            AllowPaging="true"
                            PagerHorizontalAlign="HorizontalAlign.Left"
                            ShowPagingSummary="true"
                            IsLoading="false"
                            LoadData="@LoadData"
                            RowRender="@RowRender"
                            Count="@searchApiResourcesState.Value.ActiveCount"
                            Data="@searchApiResourcesState.Value.ActiveApiResources"
                            TItem="SelectableApiResource"
                            ColumnWidth="300px">
                <Columns>
                    <RadzenDataGridColumn TItem="SelectableApiResource" Filterable="false" Sortable="false" Width="80px" TextAlign="TextAlign.Center">
                        <HeaderTemplate>
                            <RadzenCheckBox @bind-Value=@selectAllActive Change="@(args => ToggleActiveAll(args))" TValue="bool" />
                        </HeaderTemplate>
                        <Template Context="data">
                            <RadzenCheckBox @bind-Value=@data.IsSelected Change="@(args => ToggleActiveChanged(args, data))" TValue="bool" />
                        </Template>
                    </RadzenDataGridColumn>
                    <RadzenDataGridColumn TItem="SelectableApiResource" Property="Value.Name" Title="@Global.Resource" Filterable="false" Sortable="false" Width="80px" />
                    <RadzenDataGridColumn TItem="SelectableApiResource" Property="Value.Audience" Title="@Global.Audience" Filterable="false" Sortable="false" Width="80px" />
                    <RadzenDataGridColumn TItem="SelectableApiResource" Property="Value.Description" Title="@Global.Description" Filterable="false" Sortable="false" Width="80px" />
                </Columns>
            </RadzenDataGrid>
        </RadzenColumn>
    </RadzenRow>
</div>

@code {
    bool selectAllAvailable = false;
    bool selectAllActive = false;
    RadzenDataGrid<SelectableApiResource> grid;

    [Parameter]
    public SimpleIdServer.IdServer.Domains.Scope Scope { get; set; }

    protected override void OnAfterRender(bool firstRender)
    {
        base.OnAfterRender(firstRender);
        if (firstRender)
        {            
            SubscribeToAction<UpdateApiScopeResourcesSuccessAction>((act) =>
            {
                notificationService.Notify(new NotificationMessage { Severity = NotificationSeverity.Success, Summary = Global.ScopeResourcesUpdated });
                StateHasChanged();
            });
            SubscribeToAction<UnassignApiResourcesSuccessAction>((act) =>
            {
                notificationService.Notify(new NotificationMessage { Severity = NotificationSeverity.Success, Summary = Global.ScopeResourcesUpdated });
                StateHasChanged();
            });
            SubscribeToAction<RemoveSelectedApiResourcesSuccessAction>((act) =>
            {
                notificationService.Notify(new NotificationMessage { Severity = NotificationSeverity.Success, Summary = Global.ScopeResourcesRemoved });
                StateHasChanged();
            });
            grid.Reload();
        }
    }

    void ToggleAvailableChanged(bool isSelected, SelectableApiResource apiResource)
    {
        var act = new ToggleAvailableApiResourceSelectionAction { IsSelected = isSelected, ResourceName = apiResource.Value.Name };
        dispatcher.Dispatch(act);
    }

    void ToggleActiveChanged(bool isSelected, SelectableApiResource apiResource)
    {
        var act = new ToggleActiveApiResourceSelectionAction { IsSelected = isSelected, ResourceName = apiResource.Value.Name };
        dispatcher.Dispatch(act);
    }

    void ToggleAvailableAll(bool isSelected)
    {
        var act = new ToggleAllAvailableApiResourceSelectionAction { IsSelected = isSelected };
        dispatcher.Dispatch(act);
    }

    void ToggleActiveAll(bool isSelected)
    {
        var act = new ToggleAllActiveApiResourceSelectionAction { IsSelected = isSelected };
        dispatcher.Dispatch(act);
    }

    void RowRender(RowRenderEventArgs<SelectableApiResource> row)
    {
        const string className = "class";
        if (row.Data.IsNew)
            row.Attributes.Add(className, "new");
        else if (row.Data.IsSelected)
            row.Attributes.Add(className, "active");
        else if (row.Attributes.ContainsKey(className))
            row.Attributes.Remove(className);
    }

    void Unassign()
    {
        var apiResources = searchApiResourcesState.Value.ActiveApiResources.Where(r => !r.IsSelected).Select(r => r.Value.Name).ToList();
        var act = new UnassignApiResourcesAction { Id = Scope.Id, Resources = apiResources };
        dispatcher.Dispatch(act);
    }

    void Assign()
    {
        var selectedApiResources = searchApiResourcesState.Value.AvailableApiResources.Where(r => r.IsSelected).Select(r => r.Value.Name);
        var apiResources = searchApiResourcesState.Value.ActiveApiResources.Select(r => r.Value.Name).ToList();
        apiResources.AddRange(selectedApiResources);
        dispatcher.Dispatch(new UpdateApiScopeResourcesAction { Id = Scope.Id, Resources = apiResources  });
    }

    void LoadData(LoadDataArgs args)
    {
        var act = new SearchApiResourcesAction { Filter = args.Filter, OrderBy = args.OrderBy, Skip = args.Skip, Take = args.Top, ScopeName = Scope.Name };
        dispatcher.Dispatch(act);
    }

    void ShowMoreContextMenu(SelectableApiResource resource, MouseEventArgs args)
    {
        contextMenuService.Open(args, new List<ContextMenuItem>
        {
            new ContextMenuItem { Text = Global.Delete, Value = 1 }
        }, (a) =>
        {
            if (a.Value.Equals(1))
            {
                var resourceIds = searchApiResourcesState.Value.AvailableApiResources.Where(s => s.IsSelected).Select(s => s.Value.Id).ToList();
                var act = new RemoveSelectedApiResourcesAction { ResourceIds = resourceIds };
                dispatcher.Dispatch(act);
                contextMenuService.Close();
            }
        });
    }

    async void AddResource() 
    {
        await dialogService.OpenAsync<AddApiResourceDialog>(Global.AddApiResource, new Dictionary<string, object>(), new DialogOptions
        {
            Width = "700px",
            Height ="512px",
            Resizable = true,
            Draggable = true
        });
    }
}